NLLLossGrad
NLLLoss 的反向:由上游损失梯度反传得到对 logits / log_probs 的梯度。
仅在真实类别位置写入非零值,其余类别位置为 0。
设 batch 为 \(N\),类别数为 \(C\)。logits / logits_grad 形状为
\(N \times C\),labels 长度为 \(N\),weight 长度为 \(C\)。
logits 仅占位,计算不读其数值。
对样本 \(i\),令 \(y_i = \mathrm{labels}[i]\),\(w_i = \mathrm{weight}[y_i]\),
\(W = \mathrm{total\_weight}\)。先将 logits_grad 清零,再写:
reduction_type 约定(本算子编码,与前向 NLLLoss 不同):
0:Sum,使用标量loss_grad[0]
1:Mean,使用标量loss_grad[0]与total_weight
2:None,使用逐样本loss_grad[i]
- 输入:
logits - 前向输入地址,形状
[batch, class_num],不参与数值计算loss_grad - 上游梯度;Sum / Mean 时用
loss_grad[0],None 时长度为batchlabels - 标签索引,形状
[batch]params -
long long参数数组,长度至少 5,布局见下core_mask - 核掩码(仅共享存储版本使用)
params 布局:
[0]weight- 类别权重数组地址
[1]total_weight- 权重和地址,Mean 时使用
[2]batch- batch 大小 \(N\)
[3]class_num- 类别数 \(C\)
[4]reduction_type- 归约方式,取值{0,1,2}
- 输出:
logits_grad - 输出梯度,形状
[batch, class_num]
- 支持平台:
FT78NEMT7004
备注
FT78NE 支持 fp32
MT7004 支持 fp16、fp32
labels[i]需满足 \(0 \le y_i < C\)本算子
reduction_type为0/1/2,即 Sum / Mean / None;与前向NLLLoss的0/1/2,即 None / Sum / Mean 不一致,调用时勿混用
共享存储版本:
-
void hp_nll_loss_grad_s(float16 *logits, float16 *loss_grad, int *labels, float16 *logits_grad, long long *params, int core_mask)
-
void fp_nll_loss_grad_s(float *logits, float *loss_grad, int *labels, float *logits_grad, long long *params, int core_mask)
C调用示例:
1// MT7004 示例(共享存储多核,DDR 地址)
2void TestNllLossGradSMCFp32(int core_mask) {
3 int core_id = get_core_id();
4 int logic_core_id = GetLogicCoreId(core_mask, core_id);
5 int core_num = GetCoreNum(core_mask);
6 float *logits = (float *)0x81000000;
7 float *loss_grad = (float *)0x82000000;
8 int *labels = (int *)0x83000000;
9 float *weight = (float *)0x84000000;
10 float *total_weight = (float *)0x85000000;
11 float *logits_grad = (float *)0x86000000;
12 long long params[5];
13 params[0] = (long long)weight;
14 params[1] = (long long)total_weight;
15 params[2] = 16; // batch
16 params[3] = 16; // class_num
17 params[4] = 2; // reduction_type = None
18 sys_bar(0, core_num);
19 fp_nll_loss_grad_s(logits, loss_grad, labels, logits_grad, params, core_mask);
20}
21
22void main() {
23 int core_mask = 0b1111;
24 TestNllLossGradSMCFp32(core_mask);
25}
私有存储版本:
-
void hp_nll_loss_grad_p(float16 *logits, float16 *loss_grad, int *labels, float16 *logits_grad, long long *params)
-
void fp_nll_loss_grad_p(float *logits, float *loss_grad, int *labels, float *logits_grad, long long *params)
C调用示例:
1// MT7004 示例(私有存储单核,AM 地址)
2void TestNllLossGradAMFp32(void) {
3 float *logits = (float *)0x10010000;
4 float *loss_grad = (float *)0x10020000;
5 int *labels = (int *)0x10030000;
6 float *weight = (float *)0x10040000;
7 float *total_weight = (float *)0x10050000;
8 float *logits_grad = (float *)0x10060000;
9 long long params[5];
10 params[0] = (long long)weight;
11 params[1] = (long long)total_weight;
12 params[2] = 16; // batch
13 params[3] = 16; // class_num
14 params[4] = 2; // reduction_type = None
15 fp_nll_loss_grad_p(logits, loss_grad, labels, logits_grad, params);
16}
17
18void main() {
19 TestNllLossGradAMFp32();
20}